package commfunc

import (
	"context"
	"cronjob_work/common/config"
	"cronjob_work/common/etcdclient"
	"cronjob_work/common/jobs"
	"cronjob_work/common/libs"
	"cronjob_work/internal/model/entity"
	"cronjob_work/internal/service"
	"encoding/json"
	"github.com/gogf/gf/v2/frame/g"
	"strconv"
	"strings"
	"time"
)

// Init 初始化etcd,并且获取config部分key
func Init(ctx context.Context) (err error, keyprefix string, pool int, cient *etcdclient.EtcdCient) {
	dataConfig := config.Newconfig()
	result := dataConfig.GetStringArr(ctx, "etcd.url")
	key := dataConfig.GetString(ctx, "etcd.prefix")
	username := dataConfig.GetString(ctx, "etcd.username")
	password := dataConfig.GetString(ctx, "etcd.password")
	pool = dataConfig.GetInt(ctx, "jobs.pool")
	etcdclient, err := etcdclient.NewClient(ctx, result, username, password, 15*time.Second)
	if err != nil {
		g.Log().Error(ctx, err.Error())
		return err, "", 0, nil
	}

	return nil, key, pool, etcdclient
}

func InitEtcd(ctx context.Context, key string, etcdClient *etcdclient.EtcdCient) {
	if data, err := etcdClient.GetPrefix(ctx, key); err != nil {
		g.Log().Error(ctx, "etcd error"+err.Error())
		return
	} else {

		if len(data) == 0 {
			g.Log().Info(ctx, "current time the data is empty======================")
			return
		}

		jobs.InitJobsEtcd(ctx, data)
	}
}

// datatype:0  创建 1 修改 2 删除
func WatchCallback(ctx context.Context, data []byte, datatype int) {
	switch datatype {
	case 0:
		g.Log().Info(ctx, "创建", string(data))
		err := jobs.TaskToJob(ctx, data)
		if err != nil {
			g.Log().Error(ctx, err.Error())
		}
	case 1:
		g.Log().Info(ctx, "修改", string(data))
		var task *entity.PpTask
		if err := json.Unmarshal(data, &task); err != nil {
			return
		}

		TaskServerIdsArr := strings.Split(task.ServerIds, ",")
		if len(TaskServerIdsArr) > 0 {
			taskId := int(task.Id)
			for _, v := range TaskServerIdsArr {
				serverIdInt, _ := strconv.Atoi(v)
				jobKey := libs.JobKey(taskId, serverIdInt)
				jobs.RemoveJob(jobKey)
			}
		}

		if err := jobs.TaskToJob(ctx, data); err != nil {
			g.Log().Error(ctx, err.Error())
		}

	case 2:
		etcdKey := string(data)
		g.Log().Info(ctx, "删除----", etcdKey) // 删除的返回的是key的[]byte
		deljobs(ctx, etcdKey)
	default:
		g.Log().Info(ctx, "无效类型")
	}
}

// 根据etcd的key，删除cron 中jobs对应的值， 默认约定etcd的key 格式： node0/mainkey , 其中node0 配置文件中的当前节点key; mainkey 是数据库主键id
func deljobs(ctx context.Context, jobsKey string) bool {
	if strings.Contains(jobsKey, "/") == false {
		return false
	}

	strArr := strings.Split(jobsKey, "/")
	if len(strArr) < 2 {
		return false
	}

	mainkey, err := strconv.Atoi(strArr[1])
	if err != nil {
		g.Log().Error(ctx, err.Error())
		return false
	}

	task, err := service.Task().TaskGetById(ctx, mainkey)
	if err != nil {
		g.Log().Error(ctx, err.Error())
		return false
	}

	TaskServerIdsArr := strings.Split(task.ServerIds, ",")
	if len(TaskServerIdsArr) > 0 {
		taskId := int(task.Id)
		for _, v := range TaskServerIdsArr {
			serverIdInt, _ := strconv.Atoi(v)
			jobKey := libs.JobKey(taskId, serverIdInt)
			jobs.RemoveJob(jobKey)
		}
	}

	return true
}
